package com.iplant.wms.serviceImpl.dao.asn;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.wms.service.po.asn.WMSInspectTaskItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class WMSInspectTaskItemDAO extends BaseDAO {

    private static Logger logger = LoggerFactory.getLogger(WMSInspectTaskItemDAO.class);

    private static WMSInspectTaskItemDAO Instance = null;

    private WMSInspectTaskItemDAO() {
        super();
        setTableName("wms_inspecttaskitem");
    }

    public static WMSInspectTaskItemDAO getInstance() {
        if (Instance == null) {
            Instance = new WMSInspectTaskItemDAO();
        }
        return Instance;
    }





    /**
     * 添加或修改
     *
     * @param wWMSInspectTaskItem
     * @return
     */
    public int WMS_UpdateInspectTaskItem(
            BMSEmployee wLoginUser, WMSInspectTaskItem wWMSInspectTaskItem, OutResult<Integer> wErrorCode) {
        int wResult = 0;
        try {
            if (wWMSInspectTaskItem == null || wWMSInspectTaskItem.TaskID <= 0 || StringUtils.isEmpty(
                    wWMSInspectTaskItem.TaskCode) || StringUtils.isEmpty(wWMSInspectTaskItem.Name)) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return wResult;
            }
            if (StringUtils.isEmpty(wWMSInspectTaskItem.Code)) {
                wWMSInspectTaskItem.Code = wWMSInspectTaskItem.TaskCode + "_" + wWMSInspectTaskItem.Name;
            }
            wResult = this.UpdatePo(wLoginUser, wWMSInspectTaskItem, wErrorCode);


        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 删除集合
     *
     * @param wList
     */
    public void WMS_DeleteInspectTaskItemList(
            BMSEmployee wLoginUser, List<WMSInspectTaskItem> wList, OutResult<Integer> wErrorCode) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            if (wList == null || wList.size() == 0) {
                return;
            }

            List<String> wIDList = new ArrayList<String>();
            int wRows = 0;
            for (WMSInspectTaskItem wWMSInspectTaskItem : wList) {
                wRows = this.DeletePO(wLoginUser, wWMSInspectTaskItem, wErrorCode);
                if (wRows > 0) {

                    //删除检验数据 todo
//                    IPTValueDAO.getInstance().IPT_DeleteValueList(
//                            wLoginUser, wWMSInspectTaskItem.ID, IPTMode.Material.getValue(), wErrorCode);
                }
            }
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }

    }

    /**
     * 删除集合
     */
    public void WMS_DeleteInspectTaskItemList(BMSEmployee wLoginUser, int wTaskID, OutResult<Integer> wErrorCode) {
        try {
            if (wTaskID <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }
            Map<String, Object> wDeleteParams = new HashMap<>();
            wDeleteParams.put("TaskID", wTaskID);

            int wRows = this.Delete(wDeleteParams, " and ID>0 ");

            if (wRows > 0) {
//    todo             IPTValueDAO.getInstance().IPT_DeleteValueList(
//                        wLoginUser, wTaskID, IPTMode.Material.getValue(), wErrorCode);
            }
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("WMS_DeleteInspectTaskItemList", ex);
        }

    }


    /**
     * 删除集合
     */
    public void WMS_DeleteInspectTaskItemList(
            BMSEmployee wLoginUser, String wArrivalNoticeCode, String wArrivalNoticeItemCode,
            OutResult<Integer> wErrorCode) {
        try {
            if (StringUtils.isEmpty(wArrivalNoticeCode) && StringUtils.isEmpty(wArrivalNoticeItemCode)) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }
            Map<String, Object> wParams = new HashMap<>();

            //删除所有检验数据
            String wSQL = StringUtils.Format(
                    "delete t0,t from {0}.wms_inspecttaskitem t INNER JOIN {0}.wms_inspecttask t1 ON  t.TaskID=t1.ID " +
                    "LEFT JOIN  {0}.ipt_value t0  ON t0.TaskID=t.ID and t0.IPTMode=:IPTMode " +
                    " where  t.ID>0 AND t1.ID>0 AND t1.ArrivalNoticeCode=:ArrivalNoticeCode " +
                    " and  (:ArrivalNoticeCode = '''' or t1.ArrivalNoticeItemCode=:ArrivalNoticeCode) ;",
                    DBSchemas.Basic.getDBName(this.SQLType));

            wParams.put("ArrivalNoticeItemCode", wArrivalNoticeItemCode);
            wParams.put("IPTMode", 5);
            wParams.put("ArrivalNoticeCode", wArrivalNoticeCode);
            this.update(wSQL, wParams);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("WMS_DeleteInspectTaskList", ex);
        }

    }


    /**
     * 查单条
     *
     * @return
     */
    public WMSInspectTaskItem WMS_QueryInspectTaskItem(
            BMSEmployee wLoginUser, int wID, String wCode, OutResult<Integer> wErrorCode) {
        WMSInspectTaskItem wResult = new WMSInspectTaskItem();
        try {

            List<WMSInspectTaskItem> wList = null;
            if (wID > 0) {
                wList = this.WMS_QueryInspectTaskItemList(wLoginUser, StringUtils.parseListArgs(wID), "", "", "", "",
                        "", -1, -1, -1, -1, -1, "", "", "", -1, CalendarTool.getBasicDate(),
                        CalendarTool.getBasicDate(), Pagination.getMaxSize(), wErrorCode);
            } else if (StringUtils.isNotEmpty(wCode)) {
                wList = this.WMS_QueryInspectTaskItemList(wLoginUser, null, wCode, "", "", "", "", -1, -1, -1, -1, -1,
                        "", "", "", -1, CalendarTool.getBasicDate(), CalendarTool.getBasicDate(),
                        Pagination.getMaxSize(), wErrorCode);
            }
            if (wList == null || wList.size() != 1) {
                return wResult;
            }
            wResult = wList.get(0);
        } catch (Exception e) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("WMS_QueryInspectTaskItem", e);
        }
        return wResult;
    }


    public List<WMSInspectTaskItem> WMS_SelectInspectTaskItemListByOrder(
            BMSEmployee wLoginUser, String wPurchaseOrderCode, String wPurchaseOrderItemCode,
            OutResult<Integer> wErrorCode) {

        return this.WMS_QueryInspectTaskItemList(wLoginUser, null, "", wPurchaseOrderCode, wPurchaseOrderItemCode, "",
                "", -1, -1, -1, -1, -1, "", "", "", -1, CalendarTool.getBasicDate(), CalendarTool.getBasicDate(),
                Pagination.getMaxSize(), wErrorCode);
    }


    public List<WMSInspectTaskItem> WMS_SelectInspectTaskItemListByNotice(
            BMSEmployee wLoginUser, String wArrivalNoticeCode, String wArrivalNoticeItemCode,
            OutResult<Integer> wErrorCode) {

        return this.WMS_QueryInspectTaskItemList(wLoginUser, null, "", "", "", wArrivalNoticeCode,
                wArrivalNoticeItemCode, -1, -1, -1, -1, -1, "", "", "", -1, CalendarTool.getBasicDate(),
                CalendarTool.getBasicDate(), Pagination.getMaxSize(), wErrorCode);
    }

    public List<WMSInspectTaskItem> WMS_QueryInspectTaskItemList(
            BMSEmployee wLoginUser, String wPurchaseOrderCode, String wPurchaseOrderItemCode, String wArrivalNoticeCode,
            String wArrivalNoticeItemCode, int wTypeID, int wIPTStatus, int wInspectorID, int wInspectResult,
            int wStoreID, String wStoreCode, String wMaterialNo, String wMaterialName, int wActive, Calendar wStartTime,
            Calendar wEndTime, Pagination wPagination, OutResult<Integer> wErrorCode) {

        return this.WMS_QueryInspectTaskItemList(wLoginUser, null, "", wPurchaseOrderCode, wPurchaseOrderItemCode,
                wArrivalNoticeCode, wArrivalNoticeItemCode, wTypeID, wIPTStatus, wInspectorID, wInspectResult, wStoreID,
                wStoreCode, wMaterialNo, wMaterialName, wActive, wStartTime, wEndTime, wPagination, wErrorCode);

    }


    /**
     * 条件查询集合
     *
     * @return
     */
    private List<WMSInspectTaskItem> WMS_QueryInspectTaskItemList(
            BMSEmployee wLoginUser, List<Integer> wIDs, String wCode, String wPurchaseOrderCode,
            String wPurchaseOrderItemCode, String wArrivalNoticeCode, String wArrivalNoticeItemCode, int wTypeID,
            int wIPTStatus, int wInspectorID, int wInspectResult, int wStoreID, String wStoreCode, String wMaterialNo,
            String wMaterialName, int wActive, Calendar wStartTime, Calendar wEndTime, Pagination wPagination,
            OutResult<Integer> wErrorCode) {
        List<WMSInspectTaskItem> wResultList = new ArrayList<WMSInspectTaskItem>();
        try {
            if (wIDs == null) {
                wIDs = new ArrayList<>();
            }
            wIDs.removeIf(p -> p <= 0);
            Calendar wBaseTime = CalendarTool.getBasicDate();
            if (wStartTime == null) {
                wStartTime = wBaseTime;
            }
            if (wEndTime == null) {
                wEndTime = wBaseTime;
            }
            if (wStartTime.compareTo(wEndTime) > 0) {
                return wResultList;
            }
            String wSQL = StringUtils.Format(
                    "SELECT t.*,t01.ArrivalNoticeCode,t01.ArrivalNoticeItemCode,t0.Description as ArrivalNoticeDesc," +
                    " t12.Name as ArrivalNoticeItemName, t11.Description as ArrivalNoticeItemDesc,t0.PurchaseOrderCode,t12.PurchaseOrderItemCode," +
                    " t01.Active as IPTStatus,t01.TypeID,t1.Name as TypeName,t1.Code as TypeCode,  t12.MaterialNumber, " +
                    " t2.Name as CustomerName,t2.Code as CustomerCode, t5.Name as SupplierName,t5.Code as SupplierCode," +
                    " t6.Name as StoreName,t6.Code as StoreCode,t7.MaterialName, t3.Name as CreatorName ,t4.Name as EditorName  ,t41.Name as InspectorName," +
                    " t01.PackageRuleCode,t9.Description as PackageRuleName ,t01.IPTStandardCode, t10.Description as IPTStandardName FROM {0}.wms_inspecttaskitem t" +
                    " left join {0}.wms_inspecttask t01 on t.TaskID = t01.ID" +
                    " left join {0}.wms_arrivalnotice t0 on t01.ArrivalNoticeCode = t0.Code" +
                    " left join {0}.wms_arrivalnoticeitem t12 on t01.ArrivalNoticeItemCode = t12.Code" +
                    " left join {0}.wms_ordertype t1 on t01.TypeID=t1.ID " +
                    " left join {0}.mbs_user t3 on t.CreatorID=t3.ID " +
                    " left join {0}.mbs_user t4 on t.EditorID=t4.ID " +
                    " left join {0}.mbs_user t41 on t.InspectorID=t41.ID " +
                    " left join {0}.wms_store t6 on t.StoreID=t6.ID " +
                    " left join {0}.mss_material t7 on t01.MaterialNo=t7.Code " +
                    " left join {0}.mss_unit t8 on t7.CYUnitID=t8.ID " +
                    " left join {0}.mss_packagerule t9 on t.PackageRuleCode=t9.Code " +
                    " left join {0}.ipt_standard t10 on t01.IPTStandardCode=t10.Code " +
                    " WHERE ( :ID = '''' or  t.ID IN (''{1}'') ) and ( :Code ='''' or :Code = t.Code ) " +
                    "  and ( :PurchaseOrderCode ='''' or :PurchaseOrderCode = t0.PurchaseOrderCode ) " +
                    "  and ( :PurchaseOrderItemCode ='''' or :PurchaseOrderItemCode = t12.PurchaseOrderItemCode ) " +
                    "  and ( :ArrivalNoticeCode ='''' or :ArrivalNoticeCode = t.ArrivalNoticeCode ) " +
                    "  and ( :ArrivalNoticeItemCode ='''' or :ArrivalNoticeItemCode = t.ArrivalNoticeItemCode ) " +
                    " and ( :TypeID <= 0 or :TypeID = t0.TypeID ) " +
                    " and ( :IPTStatus < 0 or :IPTStatus = t0.Active ) " +
                    " and ( :Active < 0 or :Active = t.Active ) " +
                    " and ( :InspectorID <= 0 or :InspectorID = t.InspectorID ) " +
                    " and ( :InspectResult < 0 or :InspectResult = t.InspectResult ) " +
                    " and ( :StoreID <= 0 or :StoreID = t.StoreID ) " +
                    " and ( :StoreCode = '''' or  t6.Code  like :StoreCode  ) " +
                    " and ( :MaterialNo = '''' or  t.MaterialNo  = :MaterialNo  ) " +
                    " and ( :MaterialName = '''' or  t7.MaterialName  like :MaterialName or  t.MaterialNo  like :MaterialName ) " +
                    " and ( :StartTime <=str_to_date(''2010-01-01'', ''%Y-%m-%d'')  or :StartTime <=  t.InspectTime ) " +
                    " and ( :EndTime <=str_to_date(''2010-01-01'', ''%Y-%m-%d'')  or :EndTime >=  t.InspectTime ) group by t.ID ",
                    super.getDBName(), StringUtils.Join("','", wIDs));

            Map<String, Object> wParamMap = new HashMap<String, Object>();
            wParamMap.put("ID", StringUtils.Join("','", wIDs));
            wParamMap.put("Code", wCode);
            wParamMap.put("PurchaseOrderCode", wPurchaseOrderCode);
            wParamMap.put("PurchaseOrderItemCode", wPurchaseOrderItemCode);
            wParamMap.put("ArrivalNoticeCode", wArrivalNoticeCode);
            wParamMap.put("ArrivalNoticeItemCode", wArrivalNoticeItemCode);
            wParamMap.put("TypeID", wTypeID);
            wParamMap.put("IPTStatus", wIPTStatus);
            wParamMap.put("Active", wActive);
            wParamMap.put("InspectorID", wInspectorID);
            wParamMap.put("InspectResult", wInspectResult);
            wParamMap.put("StoreID", wStoreID);
            wParamMap.put("StoreCode", wStoreCode);
            wParamMap.put("MaterialNo", wMaterialNo);
            wParamMap.put("MaterialName", wMaterialName);
            wParamMap.put("StartTime", wStartTime);
            wParamMap.put("EndTime", wEndTime);

            wSQL = this.DMLChange(wSQL);


            wResultList = this.QueryForList(wSQL, wParamMap, wPagination, WMSInspectTaskItem.class);

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error(ex.toString());
        }
        return wResultList;
    }


}
